(-) describe & visualize relationship between variables (multivariate) (-) correlation plots (-) gather interesting observations for further investigation (-) gather possible new features for extraction
todos: (-) …
| https://www.kaggle.com/sobhanmoosavi/us-weather-events https://smoosavi.org/datasets/lstw |
| Moosavi, Sobhan, Mohammad Hossein Samavatian, Arnab Nandi, Srinivasan Parthasarathy, and Rajiv Ramnath. “Short and Long-term Pattern Discovery Over Large-Scale Geo-Spatiotemporal Data.” In Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining, ACM, 2019. |
| Weather event is a spatiotemporal entity, where such an entity is associated with location and time. Following is the description of available weather event types: |
| Severe-Cold: The case of having extremely low temperature, with temperature below -23.7 degrees of Celsius. Fog: The case where there is low visibility condition as a result of fog or haze. Hail: The case of having solid precipitation including ice pellets and hail. Rain: The case of having rain, ranging from light to heavy. Snow: The case of having snow, ranging from light to heavy. Storm: The extremely windy condition, where the wind speed is at least 60 km/h. Other Precipitation: Any other type of precipitation which cannot be assigned to previously described event types. |
| The weather data is provided in terms of a CSV file with the following attributes: Attribute Description Nullable 1 EventId This is the identifier of a record No 2 Type The type of an event; examples are rain and snow. No 3 Severity The severity of an event, wherever applicable. Yes 4 StartTime (UTC) The start time of an event in UTC time zone. No 5 EndTime (UTC) The end time of an event in UTC time zone. No 6 TimeZone The US-based timezone based on the location of an event No (eastern, central, mountain, and pacific). 7 LocationLat The latitude in GPS coordinate. Yes 8 LocationLng The longitude in GPS coordinate. Yes 9 AirportCode The airport station that a weather event is reported from. Yes 10 City The city in address record. Yes 11 County The county in address record. Yes 12 State The state in address record. Yes 13 ZipCode The zipcode in address record. Yes |
insights
- spearman correlation is rang based and needs at least ordinal scale, thus Type and City are out there is a small positive correlation between StartTime and Severity, since StartTime is mostly the increase in time over the years, thus Severity might gone up a little
- in Severity there are some gaps eg Rain and Snow have no Severe, where Fog has only Severe and Moderate, Cold and Storm come only in Severe, Hail only has Other these gaps make things hard to compare in Light Rain is most, but already in Moderate there is more Fog (because of Los Angeles)
- Fog seems to be longer than Rain, especially in Houston and Los Angeles; Los Angeles has no Snow but longer Cold periods (comparable to New York); Snow longest in New York and Seattle, but Seattle has less Cold, overall quite some severe fog overall
- Light and Moderate events are the most, there are less Severe events but there are also as long; Severe events in Houston and Seattle are quite long, Moderate is longer than usual in Los Angeles; may be most are Fog
(!) compare 4 big cities which are all close to the coast but vary in significantly in longitude and latitude
head(weather)
summary(weather)
EventId Type Severity StartTime EndTime TimeZone LocationLat LocationLng
Length:12226 Cold : 365 Heavy : 439 Min. :2016-01-01 08:47:00 Min. :2016-01-01 09:47:00 US/Central:2900 Min. :29.98 Min. :-122.31
Class :character Fog :2920 Light :6792 1st Qu.:2017-04-08 08:59:45 1st Qu.:2017-04-08 11:06:30 US/Eastern:3656 1st Qu.:34.02 1st Qu.:-122.31
Mode :character Hail : 6 Moderate:3428 Median :2018-09-27 02:42:30 Median :2018-09-27 03:02:30 US/Pacific:5670 Median :40.78 Median : -95.36
Precipitation: 139 Other : 6 Mean :2018-08-09 22:18:52 Mean :2018-08-09 23:49:14 Mean :38.70 Mean :-100.68
Rain :8296 Severe :1422 3rd Qu.:2019-11-24 10:37:30 3rd Qu.:2019-11-24 12:37:30 3rd Qu.:47.44 3rd Qu.: -73.97
Snow : 494 UNK : 139 Max. :2020-12-31 23:22:00 Max. :2020-12-31 23:53:00 Max. :47.44 Max. : -73.97
Storm : 6
City Duration
Houston :2900 Length:12226
Los Angeles:2378 Class :difftime
New York :3656 Mode :numeric
Seattle :3292
| spearman correlation is rang based and needs at least ordinal scale, thus Type and City are out there is a small positive correlation between StartTime and Severity, since StartTime is mostly the increase in time over the years, thus Severity might gone up a little |
|
|
|
| ```r cor_all <- weather %>% # select(Type, Severity, StartTime, City, Duration) %>% select(Severity, StartTime, Duration) %>% # mutate(Type = as.numeric(Type)) %>% mutate(Severity = as.numeric(Severity)) %>% mutate(StartTime = as.numeric(StartTime)) %>% # mutate(City = as.numeric(City)) %>% mutate(Duration = as.numeric(Duration)) %>% cor(method = ‘spearman’) |
| corrplot(cor_all) ``` |
|
|
 |
|
|
|
multivariate Severity over Type
in Severity there are some gaps eg Rain and Snow have no Severe, where Fog has only Severe and Moderate, Cold and Storm come only in Severe, Hail only has Other these gaps make things hard to compare in Light Rain is most, but already in Moderate there is more Fog (because of Los Angeles)
type_severity_plot_point <- weather %>%
ggplot(aes(x = fct_infreq(Type), y = fct_infreq(Severity), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
theme_minimal() +
ggtitle("Severity over Type")
ggplotly(type_severity_plot_point)
type_severity_plot_point <- weather %>%
filter(as.numeric(Duration) < 600) %>%
ggplot(aes(x = fct_infreq(Type), y = fct_infreq(Severity), alpha = as.numeric(Duration))) +
geom_jitter(size = 0.5) +
theme_minimal() +
# facet_grid(vars(City)) +
ggtitle("Severity over Type and Duration as alpha")
ggplotly(type_severity_plot_point)
# mosaic plot from https://cran.r-project.org/web/packages/ggmosaic/vignettes/ggmosaic.html
type_severity_plot_mosaik <-weather %>%
mutate(Severity = fct_infreq(Severity)) %>% # order Severity in frequency
mutate(Type = fct_infreq(Type)) %>% # order Type in frequency
ggplot() +
geom_mosaic(aes(x = product(Type, Severity), fill=City)) + # little better to see without fill=City, fct_infreq() doesn't work here
labs(title='f(Type | Severity) f(City)') +
theme_minimal() +
ggtitle("Severity over Type")
ggplotly(type_severity_plot_mosaik)
| multivariate Duration over Type |
Fog seems to be longer than Rain, especially in Houston and Los Angeles; Los Angeles has no Snow but longer Cold periods (comparable to New York); Snow longest in New York and Seattle, but Seattle has less Cold, overall quite some severe fog overall
duration_type_plot_point <- weather %>%
ggplot(aes(x = fct_infreq(Type), y = as.numeric(Duration), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
theme_minimal() +
ggtitle("Duration over Type")
ggplotly(duration_type_plot_point)
duration_type_plot_point <- weather %>%
filter(as.numeric(Duration) < 600) %>%
ggplot(aes(x = fct_infreq(Type), y = as.numeric(Duration), col = fct_infreq(City))) +
geom_boxplot() +
theme_minimal() +
facet_grid(rows = vars(City)) +
# coord_flip() +
ggtitle("Duration over Type")
ggplotly(duration_type_plot_point)
| multivariate Duration over Severity |
Light and Moderate events are the most, there are less Severe events but there are also as long; Severe events in Houston and Seattle are quite long, Moderate is longer than usual in Los Angeles; may be most are Fog
duration_severity_plot_point <- weather %>%
ggplot(aes(x = fct_infreq(Severity), y = as.numeric(Duration), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
theme_minimal() +
ggtitle("Severity over Type")
ggplotly(duration_severity_plot_point)
duration_severity_plot_box <- weather %>%
filter(as.numeric(Duration) < 600) %>%
ggplot(aes(x = fct_infreq(Severity), y = as.numeric(Duration), col = fct_infreq(City))) +
geom_boxplot() +
theme_minimal() +
facet_grid(rows = vars(City)) +
# coord_flip() +
ggtitle("Duration over Severity")
ggplotly(duration_severity_plot_box)
LS0tDQp0aXRsZTogImRlc2NyaWJlIGFuZCB2aXN1YWxpemUgb2YgVVMgd2VhdGhlciBldmVudCBkYXRhIg0Kc3VidGl0bGU6ICJjaXR5IHNlbGVjdGlvbiAtIG11bHRpdmFyaWF0ZSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCi0tLQ0KcHVycG9zZSBvZiBub3RlYm9vaw0KLS0tDQoNCiAgKC0pIGRlc2NyaWJlICYgdmlzdWFsaXplIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHZhcmlhYmxlcyAobXVsdGl2YXJpYXRlKQ0KICAoLSkgY29ycmVsYXRpb24gcGxvdHMgDQogICgtKSBnYXRoZXIgaW50ZXJlc3Rpbmcgb2JzZXJ2YXRpb25zIGZvciBmdXJ0aGVyIGludmVzdGlnYXRpb24NCiAgKC0pIGdhdGhlciBwb3NzaWJsZSBuZXcgZmVhdHVyZXMgZm9yIGV4dHJhY3Rpb24NCiAgDQp0b2RvczoNCiAgKC0pIC4uLg0KDQotLS0NCmluZm9ybWF0aW9uDQotLS0NCmh0dHBzOi8vd3d3LmthZ2dsZS5jb20vc29iaGFubW9vc2F2aS91cy13ZWF0aGVyLWV2ZW50cw0KaHR0cHM6Ly9zbW9vc2F2aS5vcmcvZGF0YXNldHMvbHN0dw0KDQpNb29zYXZpLCBTb2JoYW4sIE1vaGFtbWFkIEhvc3NlaW4gU2FtYXZhdGlhbiwgQXJuYWIgTmFuZGksIFNyaW5pdmFzYW4gUGFydGhhc2FyYXRoeSwgYW5kIFJhaml2IFJhbW5hdGguIOKAnFNob3J0IGFuZCBMb25nLXRlcm0gUGF0dGVybiBEaXNjb3ZlcnkgT3ZlciBMYXJnZS1TY2FsZSBHZW8tU3BhdGlvdGVtcG9yYWwgRGF0YS7igJ0gSW4gUHJvY2VlZGluZ3Mgb2YgdGhlIDI1dGggQUNNIFNJR0tERCBJbnRlcm5hdGlvbmFsIENvbmZlcmVuY2Ugb24gS25vd2xlZGdlIERpc2NvdmVyeSAmIERhdGEgTWluaW5nLCBBQ00sIDIwMTkuDQoNCldlYXRoZXIgZXZlbnQgaXMgYSBzcGF0aW90ZW1wb3JhbCBlbnRpdHksIHdoZXJlIHN1Y2ggYW4gZW50aXR5IGlzIGFzc29jaWF0ZWQgd2l0aCBsb2NhdGlvbiBhbmQgdGltZS4gRm9sbG93aW5nIGlzIHRoZSBkZXNjcmlwdGlvbiBvZiBhdmFpbGFibGUgd2VhdGhlciBldmVudCB0eXBlczoNCg0KICAgIFNldmVyZS1Db2xkOiBUaGUgY2FzZSBvZiBoYXZpbmcgZXh0cmVtZWx5IGxvdyB0ZW1wZXJhdHVyZSwgd2l0aCB0ZW1wZXJhdHVyZSBiZWxvdyAtMjMuNyBkZWdyZWVzIG9mIENlbHNpdXMuDQogICAgRm9nOiBUaGUgY2FzZSB3aGVyZSB0aGVyZSBpcyBsb3cgdmlzaWJpbGl0eSBjb25kaXRpb24gYXMgYSByZXN1bHQgb2YgZm9nIG9yIGhhemUuDQogICAgSGFpbDogVGhlIGNhc2Ugb2YgaGF2aW5nIHNvbGlkIHByZWNpcGl0YXRpb24gaW5jbHVkaW5nIGljZSBwZWxsZXRzIGFuZCBoYWlsLg0KICAgIFJhaW46IFRoZSBjYXNlIG9mIGhhdmluZyByYWluLCByYW5naW5nIGZyb20gbGlnaHQgdG8gaGVhdnkuDQogICAgU25vdzogVGhlIGNhc2Ugb2YgaGF2aW5nIHNub3csIHJhbmdpbmcgZnJvbSBsaWdodCB0byBoZWF2eS4NCiAgICBTdG9ybTogVGhlIGV4dHJlbWVseSB3aW5keSBjb25kaXRpb24sIHdoZXJlIHRoZSB3aW5kIHNwZWVkIGlzIGF0IGxlYXN0IDYwIGttL2guDQogICAgT3RoZXIgUHJlY2lwaXRhdGlvbjogQW55IG90aGVyIHR5cGUgb2YgcHJlY2lwaXRhdGlvbiB3aGljaCBjYW5ub3QgYmUgYXNzaWduZWQgdG8gcHJldmlvdXNseSBkZXNjcmliZWQgZXZlbnQgdHlwZXMuDQoNClRoZSB3ZWF0aGVyIGRhdGEgaXMgcHJvdmlkZWQgaW4gdGVybXMgb2YgYSBDU1YgZmlsZSB3aXRoIHRoZSBmb2xsb3dpbmcgYXR0cmlidXRlczoNCiAgICAgIEF0dHJpYnV0ZQkgICAgICAgIERlc2NyaXB0aW9uCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bGxhYmxlDQoxCSAgICBFdmVudElkCSAgICAgICAgICBUaGlzIGlzIHRoZSBpZGVudGlmaWVyIG9mIGEgcmVjb3JkCSAgICAgICAgICAgICAgICAgICAgICAgIE5vDQoyICAgCVR5cGUJICAgICAgICAgICAgVGhlIHR5cGUgb2YgYW4gZXZlbnQ7IGV4YW1wbGVzIGFyZSByYWluIGFuZCBzbm93LgkgICAgICAgICAgTm8NCjMJICAgIFNldmVyaXR5CSAgICAgICAgVGhlIHNldmVyaXR5IG9mIGFuIGV2ZW50LCB3aGVyZXZlciBhcHBsaWNhYmxlLiAgICAgICAgCSAgICBZZXMNCjQJICAgIFN0YXJ0VGltZSAoVVRDKQkgIFRoZSBzdGFydCB0aW1lIG9mIGFuIGV2ZW50IGluIFVUQyB0aW1lIHpvbmUuICAgICAgICAgIAkgICAgTm8NCjUJICAgIEVuZFRpbWUgKFVUQykJICAgIFRoZSBlbmQgdGltZSBvZiBhbiBldmVudCBpbiBVVEMgdGltZSB6b25lLgkgICAgICAgICAgICAgICAgTm8NCjYJICAgIFRpbWVab25lCSAgICAgICAgVGhlIFVTLWJhc2VkIHRpbWV6b25lIGJhc2VkIG9uIHRoZSBsb2NhdGlvbiBvZiBhbiBldmVudCAgICAgTm8NCiAgICAgICAgICAgICAgICAgICAgICAgIChlYXN0ZXJuLCBjZW50cmFsLCBtb3VudGFpbiwgYW5kIHBhY2lmaWMpLgkNCjcJICAgIExvY2F0aW9uTGF0CSAgICAgIFRoZSBsYXRpdHVkZSBpbiBHUFMgY29vcmRpbmF0ZS4JICAgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KOCAgIAlMb2NhdGlvbkxuZwkgICAgICBUaGUgbG9uZ2l0dWRlIGluIEdQUyBjb29yZGluYXRlLgkgICAgICAgICAgICAgICAgICAgICAgICAgIFllcw0KOQkgICAgQWlycG9ydENvZGUJICAgICAgVGhlIGFpcnBvcnQgc3RhdGlvbiB0aGF0IGEgd2VhdGhlciBldmVudCBpcyByZXBvcnRlZCBmcm9tLglZZXMNCjEwCSAgQ2l0eQkgICAgICAgICAgICBUaGUgY2l0eSBpbiBhZGRyZXNzIHJlY29yZC4JICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBZZXMNCjExCSAgQ291bnR5CSAgICAgICAgICBUaGUgY291bnR5IGluIGFkZHJlc3MgcmVjb3JkLgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBZZXMNCjEyCSAgU3RhdGUJICAgICAgICAgICAgVGhlIHN0YXRlIGluIGFkZHJlc3MgcmVjb3JkLgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBZZXMNCjEzCSAgWmlwQ29kZQkgICAgICAgICAgVGhlIHppcGNvZGUgaW4gYWRkcmVzcyByZWNvcmQuCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBZZXMNCg0KLS0tDQppbnNpZ2h0cyANCi0tLQ0KICANCiAgKGkpIHNwZWFybWFuIGNvcnJlbGF0aW9uIGlzIHJhbmcgYmFzZWQgYW5kIG5lZWRzIGF0IGxlYXN0IG9yZGluYWwgc2NhbGUsIHRodXMgVHlwZSBhbmQgQ2l0eSBhcmUgb3V0DQogICAgICB0aGVyZSBpcyBhIHNtYWxsIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gU3RhcnRUaW1lIGFuZCBTZXZlcml0eSwgc2luY2UgU3RhcnRUaW1lIGlzIG1vc3RseSB0aGUgaW5jcmVhc2UgaW4gdGltZSBvdmVyIHRoZSB5ZWFycywgdGh1cyBTZXZlcml0eSBtaWdodCBnb25lIHVwIGEgbGl0dGxlDQogIChpKSBpbiBTZXZlcml0eSB0aGVyZSBhcmUgc29tZSBnYXBzIGVnIFJhaW4gYW5kIFNub3cgaGF2ZSBubyBTZXZlcmUsIHdoZXJlIEZvZyBoYXMgb25seSBTZXZlcmUgYW5kIE1vZGVyYXRlLCBDb2xkIGFuZCBTdG9ybSBjb21lIG9ubHkgaW4gU2V2ZXJlLCBIYWlsIG9ubHkgaGFzIE90aGVyIA0KICAgICAgdGhlc2UgZ2FwcyBtYWtlIHRoaW5ncyBoYXJkIHRvIGNvbXBhcmUgDQogICAgICBpbiBMaWdodCBSYWluIGlzIG1vc3QsIGJ1dCBhbHJlYWR5IGluIE1vZGVyYXRlIHRoZXJlIGlzIG1vcmUgRm9nIChiZWNhdXNlIG9mIExvcyBBbmdlbGVzKQ0KICAoaSkgRm9nIHNlZW1zIHRvIGJlIGxvbmdlciB0aGFuIFJhaW4sIGVzcGVjaWFsbHkgaW4gSG91c3RvbiBhbmQgTG9zIEFuZ2VsZXM7IExvcyBBbmdlbGVzIGhhcyBubyBTbm93IGJ1dCBsb25nZXIgQ29sZCBwZXJpb2RzIChjb21wYXJhYmxlIHRvIE5ldyBZb3JrKTsgU25vdyBsb25nZXN0IGluIE5ldyBZb3JrIGFuZCAgICAgICAgU2VhdHRsZSwgYnV0IFNlYXR0bGUgaGFzIGxlc3MgQ29sZCwgb3ZlcmFsbCBxdWl0ZSBzb21lIHNldmVyZSBmb2cgb3ZlcmFsbCANCiAgKGkpIExpZ2h0IGFuZCBNb2RlcmF0ZSBldmVudHMgYXJlIHRoZSBtb3N0LCB0aGVyZSBhcmUgbGVzcyBTZXZlcmUgZXZlbnRzIGJ1dCB0aGVyZSBhcmUgYWxzbyBhcyBsb25nOw0KICAgICAgU2V2ZXJlIGV2ZW50cyBpbiBIb3VzdG9uIGFuZCBTZWF0dGxlIGFyZSBxdWl0ZSBsb25nLCBNb2RlcmF0ZSBpcyBsb25nZXIgdGhhbiB1c3VhbCBpbiBMb3MgQW5nZWxlczsgbWF5IGJlIG1vc3QgYXJlIEZvZw0KDQotLS0NCnN0b3JpZXMNCi0tLQ0KDQogICghKSBjb21wYXJlIDQgYmlnIGNpdGllcyB3aGljaCBhcmUgYWxsIGNsb3NlIHRvIHRoZSBjb2FzdCBidXQgdmFyeSBpbiBzaWduaWZpY2FudGx5IGluIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUNCg0KLS0tDQpsb2FkIHBhY2thZ2VzDQotLS0NCmBgYHtyIGxvYWQgcGFja2FnZXMsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIyB0aWR5IGRhdGEgZnJhbWUNCmxpYnJhcnkoZ2d0aGVtZXMpICMgZm9yIGV4dHJhIHBsb3QgdGhlbWVzDQpsaWJyYXJ5KHBsb3RseSkgIyBtYWtlIGdncGxvdHMgaW50ZXJhY3RpdmUNCmxpYnJhcnkobHVicmlkYXRlKSAjIGZ1bmN0aW9ucyB0byB3b3JrIHdpdGggZGF0ZS10aW1lcyBhbmQgdGltZS1zcGFucw0KbGlicmFyeShjb3JycGxvdCkgIyBjb3JyZWxhdGlvbiBwbG90cw0KbGlicmFyeShnZ21vc2FpYykgIyBnZW9tX21vc2FpYygpIG1vc2FpYyBwbG90cyBmb3IgY2F0ZWdvcmljYWwgZGF0YQ0KbGlicmFyeShnZ3BhcmFsbGVsKSAjIHBhcmFsbGVsIGNvb3JkaW5hdGUgcGxvdHMgZm9yIGNhdGVnb3JpY2FsIGRhdGENCmBgYA0KDQotLS0NCm92ZXJ2aWV3DQotLS0NCmBgYHtyfQ0KaGVhZCh3ZWF0aGVyKQ0KYGBgDQpgYGB7cn0NCnN1bW1hcnkod2VhdGhlcikNCmBgYA0KDQotLS0NCmNvcnJlbGF0aW9uIA0KLS0tDQpzcGVhcm1hbiBjb3JyZWxhdGlvbiBpcyByYW5nIGJhc2VkIGFuZCBuZWVkcyBhdCBsZWFzdCBvcmRpbmFsIHNjYWxlLCB0aHVzIFR5cGUgYW5kIENpdHkgYXJlIG91dA0KdGhlcmUgaXMgYSBzbWFsbCBwb3NpdGl2ZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIFN0YXJ0VGltZSBhbmQgU2V2ZXJpdHksIHNpbmNlIFN0YXJ0VGltZSBpcyBtb3N0bHkgdGhlIGluY3JlYXNlIGluIHRpbWUgb3ZlciB0aGUgeWVhcnMsIHRodXMgU2V2ZXJpdHkgbWlnaHQgZ29uZSB1cCBhIGxpdHRsZQ0KDQpgYGB7cn0NCmNvcl9hbGwgPC0gd2VhdGhlciAlPiUNCiAgIyBzZWxlY3QoVHlwZSwgU2V2ZXJpdHksIFN0YXJ0VGltZSwgQ2l0eSwgRHVyYXRpb24pICU+JQ0KICBzZWxlY3QoU2V2ZXJpdHksIFN0YXJ0VGltZSwgRHVyYXRpb24pICU+JQ0KICAjIG11dGF0ZShUeXBlID0gYXMubnVtZXJpYyhUeXBlKSkgJT4lDQogIG11dGF0ZShTZXZlcml0eSA9IGFzLm51bWVyaWMoU2V2ZXJpdHkpKSAlPiUNCiAgbXV0YXRlKFN0YXJ0VGltZSA9IGFzLm51bWVyaWMoU3RhcnRUaW1lKSkgJT4lDQogICMgbXV0YXRlKENpdHkgPSBhcy5udW1lcmljKENpdHkpKSAlPiUNCiAgbXV0YXRlKER1cmF0aW9uID0gYXMubnVtZXJpYyhEdXJhdGlvbikpICU+JQ0KICBjb3IobWV0aG9kID0gJ3NwZWFybWFuJykNCiAgDQpjb3JycGxvdChjb3JfYWxsKQ0KYGBgDQoNCi0tLQ0KbXVsdGl2YXJpYXRlIFNldmVyaXR5IG92ZXIgVHlwZQ0KLS0tDQppbiBTZXZlcml0eSB0aGVyZSBhcmUgc29tZSBnYXBzIGVnIFJhaW4gYW5kIFNub3cgaGF2ZSBubyBTZXZlcmUsIHdoZXJlIEZvZyBoYXMgb25seSBTZXZlcmUgYW5kIE1vZGVyYXRlLCBDb2xkIGFuZCBTdG9ybSBjb21lIG9ubHkgaW4gU2V2ZXJlLCBIYWlsIG9ubHkgaGFzIE90aGVyIA0KdGhlc2UgZ2FwcyBtYWtlIHRoaW5ncyBoYXJkIHRvIGNvbXBhcmUgDQppbiBMaWdodCBSYWluIGlzIG1vc3QsIGJ1dCBhbHJlYWR5IGluIE1vZGVyYXRlIHRoZXJlIGlzIG1vcmUgRm9nIChiZWNhdXNlIG9mIExvcyBBbmdlbGVzKQ0KDQpgYGB7cn0NCnR5cGVfc2V2ZXJpdHlfcGxvdF9wb2ludCA8LSB3ZWF0aGVyICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfaW5mcmVxKFR5cGUpLCB5ID0gZmN0X2luZnJlcShTZXZlcml0eSksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjIsIHNpemUgPSAwLjUpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIlNldmVyaXR5IG92ZXIgVHlwZSIpDQogIA0KZ2dwbG90bHkodHlwZV9zZXZlcml0eV9wbG90X3BvaW50KSAgDQpgYGANCmBgYHtyfQ0KdHlwZV9zZXZlcml0eV9wbG90X3BvaW50IDwtIHdlYXRoZXIgJT4lDQogIGZpbHRlcihhcy5udW1lcmljKER1cmF0aW9uKSA8IDYwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IGZjdF9pbmZyZXEoVHlwZSksIHkgPSBmY3RfaW5mcmVxKFNldmVyaXR5KSwgYWxwaGEgPSBhcy5udW1lcmljKER1cmF0aW9uKSkpICsNCiAgICBnZW9tX2ppdHRlcihzaXplID0gMC41KSArDQogICAgdGhlbWVfbWluaW1hbCgpICsgDQogICAgIyBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICBnZ3RpdGxlKCJTZXZlcml0eSBvdmVyIFR5cGUgYW5kIER1cmF0aW9uIGFzIGFscGhhIikNCiAgDQpnZ3Bsb3RseSh0eXBlX3NldmVyaXR5X3Bsb3RfcG9pbnQpICANCmBgYA0KDQpgYGB7cn0NCiMgbW9zYWljIHBsb3QgZnJvbSBodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZ2dtb3NhaWMvdmlnbmV0dGVzL2dnbW9zYWljLmh0bWwNCnR5cGVfc2V2ZXJpdHlfcGxvdF9tb3NhaWMgPC13ZWF0aGVyICU+JQ0KICBtdXRhdGUoU2V2ZXJpdHkgPSBmY3RfaW5mcmVxKFNldmVyaXR5KSkgJT4lICMgb3JkZXIgU2V2ZXJpdHkgaW4gZnJlcXVlbmN5DQogIG11dGF0ZShUeXBlID0gZmN0X2luZnJlcShUeXBlKSkgJT4lICMgb3JkZXIgVHlwZSBpbiBmcmVxdWVuY3kNCiAgZ2dwbG90KCkgKw0KICAgIGdlb21fbW9zYWljKGFlcyh4ID0gcHJvZHVjdChUeXBlLCBTZXZlcml0eSksIGZpbGw9Q2l0eSkpICsgIyBsaXR0bGUgYmV0dGVyIHRvIHNlZSB3aXRob3V0IGZpbGw9Q2l0eSwgZmN0X2luZnJlcSgpIGRvZXNuJ3Qgd29yayBoZXJlDQogICAgbGFicyh0aXRsZT0nZihUeXBlIHwgU2V2ZXJpdHkpIGYoQ2l0eSknKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJTZXZlcml0eSBvdmVyIFR5cGUiKQ0KDQpnZ3Bsb3RseSh0eXBlX3NldmVyaXR5X3Bsb3RfbW9zYWljKQ0KYGBgDQoNCi0tLQ0KbXVsdGl2YXJpYXRlIER1cmF0aW9uIG92ZXIgVHlwZQ0KLS0tDQpGb2cgc2VlbXMgdG8gYmUgbG9uZ2VyIHRoYW4gUmFpbiwgZXNwZWNpYWxseSBpbiBIb3VzdG9uIGFuZCBMb3MgQW5nZWxlczsgTG9zIEFuZ2VsZXMgaGFzIG5vIFNub3cgYnV0IGxvbmdlciBDb2xkIHBlcmlvZHMgKGNvbXBhcmFibGUgdG8gTmV3IFlvcmspOyBTbm93IGxvbmdlc3QgaW4gTmV3IFlvcmsgYW5kIFNlYXR0bGUsIGJ1dCBTZWF0dGxlIGhhcyBsZXNzIENvbGQsIG92ZXJhbGwgcXVpdGUgc29tZSBzZXZlcmUgZm9nIG92ZXJhbGwNCg0KYGBge3J9DQpkdXJhdGlvbl90eXBlX3Bsb3RfcG9pbnQgPC0gd2VhdGhlciAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gZmN0X2luZnJlcShUeXBlKSwgeSA9IGFzLm51bWVyaWMoRHVyYXRpb24pLCBjb2wgPSBmY3RfaW5mcmVxKENpdHkpKSkgKw0KICAgIGdlb21faml0dGVyKGFscGhhID0gMC4yLCBzaXplID0gMC41KSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJEdXJhdGlvbiBvdmVyIFR5cGUiKQ0KDQpnZ3Bsb3RseShkdXJhdGlvbl90eXBlX3Bsb3RfcG9pbnQpDQpgYGANCmBgYHtyfQ0KZHVyYXRpb25fdHlwZV9wbG90X2JveCA8LSB3ZWF0aGVyICU+JQ0KICBmaWx0ZXIoYXMubnVtZXJpYyhEdXJhdGlvbikgPCA2MDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBmY3RfaW5mcmVxKFR5cGUpLCB5ID0gYXMubnVtZXJpYyhEdXJhdGlvbiksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9ib3hwbG90KCkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhDaXR5KSkgKw0KICAgICMgY29vcmRfZmxpcCgpICsNCiAgICBnZ3RpdGxlKCJEdXJhdGlvbiBvdmVyIFR5cGUiKQ0KDQpnZ3Bsb3RseShkdXJhdGlvbl90eXBlX3Bsb3RfYm94KQ0KYGBgDQoNCi0tLQ0KbXVsdGl2YXJpYXRlIER1cmF0aW9uIG92ZXIgU2V2ZXJpdHkNCi0tLQ0KTGlnaHQgYW5kIE1vZGVyYXRlIGV2ZW50cyBhcmUgdGhlIG1vc3QsIHRoZXJlIGFyZSBsZXNzIFNldmVyZSBldmVudHMgYnV0IHRoZXJlIGFyZSBhbHNvIGFzIGxvbmc7DQpTZXZlcmUgZXZlbnRzIGluIEhvdXN0b24gYW5kIFNlYXR0bGUgYXJlIHF1aXRlIGxvbmcsIE1vZGVyYXRlIGlzIGxvbmdlciB0aGFuIHVzdWFsIGluIExvcyBBbmdlbGVzOyBtYXkgYmUgbW9zdCBhcmUgRm9nDQoNCg0KYGBge3J9DQpkdXJhdGlvbl9zZXZlcml0eV9wbG90X3BvaW50IDwtIHdlYXRoZXIgJT4lDQogIGdncGxvdChhZXMoeCA9IGZjdF9pbmZyZXEoU2V2ZXJpdHkpLCB5ID0gYXMubnVtZXJpYyhEdXJhdGlvbiksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjIsIHNpemUgPSAwLjUpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIkR1cmF0aW9uIG92ZXIgU2V2ZXJpdHkiKQ0KDQpnZ3Bsb3RseShkdXJhdGlvbl9zZXZlcml0eV9wbG90X3BvaW50KQ0KYGBgDQpgYGB7cn0NCmR1cmF0aW9uX3NldmVyaXR5X3Bsb3RfYm94IDwtIHdlYXRoZXIgJT4lDQogIGZpbHRlcihhcy5udW1lcmljKER1cmF0aW9uKSA8IDYwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IGZjdF9pbmZyZXEoU2V2ZXJpdHkpLCB5ID0gYXMubnVtZXJpYyhEdXJhdGlvbiksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9ib3hwbG90KCkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhDaXR5KSkgKw0KICAgICMgY29vcmRfZmxpcCgpICsNCiAgICBnZ3RpdGxlKCJEdXJhdGlvbiBvdmVyIFNldmVyaXR5IikNCg0KZ2dwbG90bHkoZHVyYXRpb25fc2V2ZXJpdHlfcGxvdF9ib3gpDQpgYGANCg0KDQoNCg0KDQo=